﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using BusinessIntelligenceToolkit.Controls.ContainerGenerators;
using BusinessIntelligenceToolkit.Framework.Extensions;

namespace BusinessIntelligenceToolkit.Controls
{
    public class BitListBox : BitItemsControl
    {
        public static readonly DependencyProperty IsSelectedItemProperty =
            DependencyProperty.RegisterAttached("IsSelectedItem", typeof(bool), typeof(BitListBox), new PropertyMetadata(default(bool)));

        static BitListBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(BitListBox), new FrameworkPropertyMetadata(typeof(BitListBox)));
        }

        public BitListBox()
        {
            Loaded += (s, e) => Focus();
        }

        public static void SetIsSelectedItem(UIElement element, bool value)
        {
            element.SetValue(IsSelectedItemProperty, value);
        }

        public static bool GetIsSelectedItem(UIElement element)
        {
            return (bool)element.GetValue(IsSelectedItemProperty);
        }

        protected override void CreateContainerGenerator()
        {
            ContainerGenerator = new BitListBoxContainerGenerator(this);
        }

        protected override void OnCollectionViewChanging(ICollectionView oldCollectionView, ICollectionView newCollectionView)
        {
            base.OnCollectionViewChanging(oldCollectionView, newCollectionView);
            if (oldCollectionView != null)
            {
                oldCollectionView.CurrentChanged -= OnCurrentChanged;
            }

            if (newCollectionView != null)
            {
                newCollectionView.CurrentChanged += OnCurrentChanged;
                Select(newCollectionView.CurrentItem);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Select(e.OriginalSource as DependencyObject);
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            if (e.Key == Key.Down)
            {
                var success = CollectionView.MoveCurrentToNext();
                if (!success)
                {
                    CollectionView.MoveCurrentToPrevious();
                }
            }

            if (e.Key == Key.Up)
            {
                var success = CollectionView.MoveCurrentToPrevious();
                if (!success)
                {
                    CollectionView.MoveCurrentToNext();
                }
            }
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            Select(e.OriginalSource as DependencyObject);
        }

        private void OnCurrentChanged(object sender, EventArgs e)
        {
            Select(CollectionView.CurrentItem);
        }

        private void Select(DependencyObject obj)
        {
            ContentPresenter container = obj.FindAncestor<ContentPresenter>(this);

            if (container != null)
            {
                foreach (ContentPresenter cont in Containers)
                {
                    cont.SetValue(IsSelectedItemProperty, false);
                }

                container.SetValue(IsSelectedItemProperty, true);

                SelectedItems.Clear();
                SelectedItems.Add(container.Content);

                var listCollectionView = CollectionView as ListCollectionView;
                if (listCollectionView != null)
                {
                    listCollectionView.SetCurrentItem(container.Content);
                }
            }
        }

        private void Select(object obj)
        {
            foreach (ContentPresenter cont in Containers)
            {
                cont.SetValue(IsSelectedItemProperty, false);
                if (cont.Content != null && cont.Content.Equals(obj))
                {
                    cont.SetValue(IsSelectedItemProperty, true);
                }
            }

            SelectedItems.Clear();
            SelectedItems.Add(obj);
        }
    }
}